<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Sample</title>
<meta name="viewport"
            content="width=device-width, initial-scale=1.0">
<meta name="HandheldFriendly" content="true">
</head>
<body>
<canvas id="myCanvas" width="600" height="200"
        style="border:1px dashed #c3c3c3;">
   这里放置的内容用于浏览器不支持Canvas的情况
</canvas>
<fieldset style="width:280px; margin:0px; padding:10px;">
<legend>通道混合器</legend>
<label>红色：
<input type="range" id="color_r"
        min="-2" max="2" step="0.1" value="0"
        onchange="javascript:changeHandler(event);"/>
</label>
<label>
   <input type="text" id="scale_r" value="0" style="width:30px;"/>%
</label>
<br />
<label>绿色：
<input type="range" id="color_g"
        min="-2" max="2" step="0.1" value="0"
        onchange="javascript:changeHandler(event);"/>
</label>
<label>
   <input type="text" id="scale_g" value="0" style="width:30px;"/>%
</label>
<br />
<label>蓝色：
<input type="range" id="color_b"
        min="-2" max="2" step="0.1" value="0"
        onchange="javascript:changeHandler(event);"/>
</label>
<label>
   <input type="text" id="scale_b" value="0" style="width:30px;"/>%
</label>
<br />
<label>常数：
<input type="range" id="color_con"
        min="-2" max="2" step="0.1" value="0"
        onchange="javascript:changeHandler(event);"/>
</label>
<label>
   <input type="text" id="scale_con" value="0" style="width:30px;"/>%
</label>
</fieldset>
<br />
<label>单色：
<input type="checkbox" id="color_grey"
        onclick="javascript:rgb2grey(event);"/>
</label>
<script>
/**
 * 该方法用于限定取值范围。
   当paramNumber小于min时则返回minNumber，
   当大于maxNumber时则返回maxNumber，
   当在minNumber和maxNumber之间时则反回paramNumber本身。
 * @param  number   minNumber        可取的最小值
 * @param  number   maxNumber        可取的最大值
 * @param  number   paramNumber      指定的值
 * @return number
 */
function clamp(minNumber, maxNumber, paramNumber){
    if (minNumber > maxNumber) throw new Error("参数错误！");
    if (paramNumber > maxNumber) return maxNumber;
    if (paramNumber < minNumber) return minNumber;
    return paramNumber;
}
// 通道变化事件处理函数
function changeHandler(event){
   var color_r = document.getElementById("color_r");
   var color_g = document.getElementById("color_g");
   var color_b = document.getElementById("color_b");
   var color_con = document.getElementById("color_con");

   document.getElementById("scale_r").value =
                                       Math.round(color_r.value*100);
   document.getElementById("scale_g").value =
                                       Math.round(color_g.value*100);
   document.getElementById("scale_b").value =
                                       Math.round(color_b.value*100);
   document.getElementById("scale_con").value =
                                       Math.round(color_con.value*100);

   // 根据源图像创建新的ImageData
   var imgd_n = cxt.createImageData(imgd.width, imgd.height);
   var pix_n = imgd_n.data;
   var n = pix.length;
   for (var i = 0; i < n; i += 4) {
      pix_n[i  ] = clamp(0, 255, color_r.value*pix[i  ] + 0*pix[i+1] +
                                      0*pix[i+2] + color_con.value*255);
      pix_n[i+1] = clamp(0, 255, 0*pix[i  ] + color_g.value*pix[i+1] +
                                      0*pix[i+2] + color_con.value*255);
      pix_n[i+2] = clamp(0, 255, 0*pix[i  ] + 0*pix[i+1] +
                        color_b.value*pix[i+2] + color_con.value*255);
      pix_n[i+3] = pix[i+3];	
   }
   // 画ImageData对象
   cxt.clearRect(300, 0, imgd.width, imgd.height);
   cxt.putImageData(imgd_n, 300, 0);
}

// 单色事件处理函数
function rgb2grey(event){
   // 根据源图像创建新的ImageData
   var imgd_n = cxt.createImageData(imgd.width, imgd.height);
   var pix_n = imgd_n.data;
   if(event.target.value=="on"){
	  var n = pix.length;
	  for (var i = 0; i < n; i += 4) {
		 pix_n[i  ] = clamp(0, 255, 0.3*pix[i  ] + 0.59*pix[i+1] +
                                           0.11*pix[i+2]);
		 pix_n[i+1] = clamp(0, 255, 0.3*pix[i  ] + 0.59*pix[i+1] +
                                           0.11*pix[i+2]);
		 pix_n[i+2] = clamp(0, 255, 0.3*pix[i  ] + 0.59*pix[i+1] +
                                           0.11*pix[i+2]);
		 pix_n[i+3] = pix[i+3];
	  }
   } else {
	  var n = pix.length;
	  for (var i = 0; i < n; i += 4) {
	     pix_n[i  ] = pix[i  ];
	     pix_n[i+1] = pix[i+1];
	     pix_n[i+2] = pix[i+2];
	     pix_n[i+3] = pix[i+3];	
	  }
   }
   // 画ImageData对象
   cxt.clearRect(300, 0, imgd.width, imgd.height);
   cxt.putImageData(imgd_n, 300, 0);   
}

var canvas = document.getElementById("myCanvas");
var imgd;
var pix;
if (canvas && canvas.getContext) {
   var cxt = canvas.getContext("2d");
   // 创建image
   var img = new Image();
   img.src = "images/image_01.png";
   // 当图片加载完毕再绘制图片
   img.onload = function (event){
	  cxt.drawImage(img, 0, 0);
	  // 首先获取ImageData对象，因为刚才画的图片的幅面是300*200
	  // 所以，指定幅面大小也是300*200
	  imgd = cxt.getImageData(0, 0, 300, 200);
	  pix = imgd.data;
   }
}
</script>
</body>
</html>
